/*
 * Copyright (C) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup AudioEncoder
 * @{
 *
 * @brief AudioEncoder模块提供用于音频编码功能的函数。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 *
 * @since 9
 * @version 1.0
 */

/**
 * @file native_avcodec_audioencoder.h
 *
 * @brief 声明用于音频编码的Native API。
 *
 * @since 9
 * @version 1.0
 */

#ifndef NATIVE_AVCODEC_AUDIOENCODER_H
#define NATIVE_AVCODEC_AUDIOENCODER_H

#include <stdint.h>
#include <stdio.h>
#include "native_averrors.h"
#include "native_avformat.h"
#include "native_avmemory.h"
#include "native_avcodec_base.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 通过mime类型创建一个音频编码器实例，大多数情况下推荐使用该接口。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 * @param mime mime类型描述字符串，参考{@link OH_AVCODEC_MIMETYPE_AUDIO_AAC}
 * @return 返回一个指向OH_AVCodec实例的指针
 * @since 9
 * @version 1.0
 */
OH_AVCodec *OH_AudioEncoder_CreateByMime(const char *mime);

/**
 * @brief 通过音频编码器名称创建一个音频编码器实例，使用这个接口的前提是必须清楚编码器准确的名称。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 * @param name 音频编码器名称
 * @return 返回一个指向OH_AVCodec实例的指针
 * @since 9
 * @version 1.0
 */
OH_AVCodec *OH_AudioEncoder_CreateByName(const char *name);

/**
 * @brief 清空编码器内部资源，并销毁编码器实例。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 * @param codec 指向OH_AVCodec实例的指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioEncoder_Destroy(OH_AVCodec *codec);

/**
 * @brief 设置异步回调函数，使得你的应用能够响应音频编码器产生的事件，该接口被调用必须是在Prepare被调用前。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 * @param codec 指向OH_AVCodec实例的指针
 * @param callback 一个包含所有回调函数的集合体，参考{@link OH_AVCodecAsyncCallback}
 * @param userData 用户特定数据
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioEncoder_SetCallback(OH_AVCodec *codec, OH_AVCodecAsyncCallback callback, void *userData);

/**
 * @brief 配置音频编码器，典型地，需要配置被编码音频轨道的描述信息，该接口被调用必须是在Prepare被调用前。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 * @param codec 指向OH_AVCodec实例的指针
 * @param format OH_AVFormat句柄指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioEncoder_Configure(OH_AVCodec *codec, OH_AVFormat *format);

/**
 * @brief 准备编码器内部资源，调用该接口前必须先调用Configure接口。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 * @param codec 指向OH_AVCodec实例的指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioEncoder_Prepare(OH_AVCodec *codec);

/**
 * @brief 启动编码器，该接口必须在已经Prepare成功后调用。
 * 在启动成功后，编码器将开始报告{@link OH_AVCodecOnNeedInputData}事件。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 * @param codec 指向OH_AVCodec实例的指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioEncoder_Start(OH_AVCodec *codec);

/**
 * @brief 停止编码器。在停止后可通过Start重新进入Started状态。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 * @param codec 指向OH_AVCodec实例的指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioEncoder_Stop(OH_AVCodec *codec);

/**
 * @brief 清空编码器内部缓存的输入输出数据。在该接口被调用后，所有先前通过异步回调报告的Buffer的索引都将
 * 失效，确保不要再访问这些索引对应的Buffers。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 * @param codec 指向OH_AVCodec实例的指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioEncoder_Flush(OH_AVCodec *codec);

/**
 * @brief 重置编码器。如需继续编码工作，需要重新调用Configure接口以配置该编码器实例。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 * @param codec 指向OH_AVCodec实例的指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioEncoder_Reset(OH_AVCodec *codec);

/**
 * @brief 获取该编码器输出数据的描述信息，需要注意的是，返回值所指向的OH_AVFormat实例需调用者手动释放。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 * @param codec 指向OH_AVCodec实例的指针
 * @return 返回OH_AVFormat句柄指针，需调用者手动释放;
 * @since 9
 * @version 1.0
 */
OH_AVFormat *OH_AudioEncoder_GetOutputDescription(OH_AVCodec *codec);

/**
 * @brief 向编码器设置动态参数，注意：该接口仅能在编码器被启动后调用，同时错误的参数设置，可能会导致编码失败。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 * @param codec 指向OH_AVCodec实例的指针
 * @param format OH_AVFormat句柄指针
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioEncoder_SetParameter(OH_AVCodec *codec, OH_AVFormat *format);

/**
 * @brief 将填充好数据的输入Buffer提交给音频编码器。{@link OH_AVCodecOnNeedInputData}回调会报告可用的输入
 * Buffer及对应的索引值。一旦指定索引的Buffer被提交给编码器，直到再一次收到{@link OH_AVCodecOnNeedInputData}
 * 回调报告相同索引的Buffer可用前，该Buffer都不可以再次被访问。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 * @param codec 指向OH_AVCodec实例的指针
 * @param index 输入Buffer对应的索引值
 * @param attr 描述该Buffer内所包含数据的信息
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioEncoder_PushInputData(OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr);

/**
 * @brief 将处理结束的输出Buffer交还给编码器。
 * 
 * @syscap SystemCapability.Multimedia.Media.AudioEncoder
 * @param codec 指向OH_AVCodec实例的指针
 * @param index 输出Buffer对应的索引值
 * @return 执行成功返回AV_ERR_OK
 * @return 执行失败返回具体错误码，参考{@link OH_AVErrCode}
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_AudioEncoder_FreeOutputData(OH_AVCodec *codec, uint32_t index);

#ifdef __cplusplus
}
#endif

#endif // NATIVE_AVCODEC_AUDIOENCODER_H